#ifndef SHEET_H
#define SHEET_H

#include <map>
#include "Core.h"
#include "AbstractObject.h"

class ObjectFactory;

class Sheet
{
public:
	Sheet(Core* um, int id, std::string masterClass = "");
	int getId();
	
	void update(double dt);
	
	ObjectFactory* factory();
	Core* ultra();
	Filesystem* fs();

	AnyAOPtr createTopLevelObj(std::string className, std::string objName);
	AnyAOPtr getTopLevelObj(std::string objName);
	void deleteTopLevelObj(std::string objName);
	
	// Console stuff
	int addConsole(Console* hook, int channel);
	void removeConsole(Console* hook);

	void consolePrint(int channel, std::string& str);

	// pushes the function from core.lua named fname onto the stack of L
	void getLuaCoreFunc(std::string fname, lua_State* L);

	lua_State* getL();

	// Core lua interface functions

	// bool RawSetInheritance(Sheet* sh, childName, parentName)
	static int li_rawSetInheritance(lua_State* L);
	static int li_rawSetCppInheritance(lua_State* L);
	// table RawGetProto(Sheet* sh, className)
	static int li_rawGetProto(lua_State* L);
	// AOPtr CreateTopLevelObj(Sheet* sh, className, objName)
	static int li_createTopLevelObj(lua_State* L);
	// bool DeleteTopLevelObj(Sheet* sh, objName)
	static int li_deleteTopLevelObj(lua_State* L);
	// table GetTLOTable(Sheet* sh)
	static int li_getTLOTAble(lua_State* L);
	// table GetLuaProto(Sheet* sh, className)
	static int li_getLuaProto(lua_State* L);
	// int CreateSheet(Sheet* sh, className) // creates a sheet, instantiating an object
	//							  //  of classname, and registering it as a TLO
	//							  //  with the name 'master'
	static int li_createSheet(lua_State* L);
	// bool DeleteSheet(Sheet* sh, int sheetid)
	static int li_deleteSheet(lua_State* L);
	static int li_logPrint(lua_State* L);
	// Sheet* sh, int chan, string str
	static int li_conPrint(lua_State* L);
	// Sheet* sh
	static int li_quit(lua_State* L);
	// checks if its argument (table w/ .__sp) refers to a still valid AO
	// (note: doesn't take sheet as an argument)
	static int li_checkNull(lua_State* L);
	// returns the system arguments as a table thing
	static int li_getSysArgs(lua_State* L);

	~Sheet();
private:
	void execConCommand(int chan, std::string& str);
	int _id;
	Core* _um;
	std::map<std::string, AnyStrongAOPtr> _topLevelObjects;
	ObjectFactory* _of;
	lua_State* _L;
	//int _coreRef; // core assumed global for now
	int _topLevelTableRef;
	std::vector<Console*> _consoleTable[MAX_CHANNELS];
	std::vector<ConHookStub> _consoleList;
};

#endif
